let fileReader = new FileReader();
let spark = new SparkMD5();

function makeWorker(f) {
  let pendingJobs = {};

  const worker = new Worker (
    URL.createObjectURL (new Blob ([`(${f.toString ()})()`]))
  );

  worker.onmessage = ({data: {result, jobId}}) => {
    // 调用resolve，改变Promise状态
    pendingJobs[jobId] (result);
    // 删掉，防止key冲突
    delete pendingJobs[jobId];
  };

  return (message) =>
    new Promise (resolve => {
      const jobId = String (Math.random ());
      pendingJobs[jobId] = resolve;
      worker.postMessage ({jobId, message});
    });
};


const UPLOAD = {
  data: {
    md5Len: 0,
    md5hash: "",
    sdkType: "",
    fileName: "",
    webworker: null,
    sdkDir:''
  },
  watch: {
    "uploadData.md5Len": {
      handler(val) {
        if (val == 100) {
          // 通知服务器整合文件
          this.uploadStatus(
            this.uploadData.md5hash,
            this.uploadData.sdkType,
            this.uploadData.fileName
          );
        }
      },
      deep: true,
      immediate: true,
    },
  },
  methods: {
    // 上传文件到uploadfile小文件
    uploadFile({ e, projectName }, cb) {
      let file = e.target.files[0];
      let formData = new FormData();
      formData.append("name", projectName);
      formData.append("file", file);
      fetchUpload("/upload", formData).then((res) => {
        cb && cb(res);
      });
    },
    // 切片上传sdk
    async uploadSDK(file, type,sdkDir) {
      // return console.log('暂时不支持',file, type,sdkDir)
      this.uploadData.md5hash = await this.getMd5(file);
      this.uploadData.sdkType = type;
      this.uploadData.fileName = file.name;
      this.uploadData.sdkDir = sdkDir;
      console.log(
        this.uploadData.md5hash,
        this.uploadData.sdkType,
        this.uploadData.fileName,
        "md5hash, sdkType, fileName"
      );
      // 检测上传状态
      let arr = await this.uploadStatus(
        this.uploadData.md5hash,
        this.uploadData.sdkType,
        this.uploadData.fileName
      );
      if (arr.length == 0) {
        // 把文件固定切100片 无论大小 每一片携带主文件md5 和自身的md5 异步上传100片
        this.uploadFileChunk(file, this.uploadData.md5hash, type, []);
      } else if (arr.length == 1 && arr[0] == 666) {
      } else {
        // 继续上传
        this.uploadFileChunk(file, this.uploadData.md5hash, type, arr);
      }
      // 所有上传后，通知服务器整合文件
    },
    
    uploadStatus(md5, type, fileName) {
      return new Promise((resolve, reject) => {
        fetchPost("sdk/inspectUpload", { md5, type, fileName,sdkDir:this.uploadData.sdkDir }).then((res) => {
          if (res.length == 0) {
            resolve([]); // 全部上传
          } else if (res.length == 1 && res[0] == 666) {
            resolve([666]); // 完成上传
            this.uploadData.md5Len = 0;
          } else {
            resolve(res); // 继续上传
          }
        });
      });
    },
    // 1 获取文件md5值
    getMd5(file) {
      return new Promise((resolve, reject) => {
        fileReader.readAsBinaryString(file);
        fileReader.onload = (e) => {
          spark.appendBinary(e.target.result);
          resolve(spark.end());
        };
        fileReader.onerror = (err) => {
          console.warn("oops, something went wrong.", err);
          resolve("66666666666");
        };
      });
    },
    // 2.把文件固定切100片 无论大小 每一片携带主文件md5 和自身的md5 异步上传100片
    async uploadFileChunk(file, md5, type, arr) {
      // 1 切成100片
      // 获取文件大小 然后切片最后一片一定是到最后
      let size = file.size;
      let chunkSize = Math.ceil(size / 100);
      let start = 0;
      let end = chunkSize;
      let index = 0;
      if (arr.length > 0 && arr.includes(index)) {
        this.uploadData.md5Len = 100 - arr.length;
      } else if (arr.length == 0) {
        this.uploadData.md5Len = 0;
      }

      // 循环切片
      while (start < size) {
        if (index == 99) end = size;
        let chunk = file.slice(start, end);
        let chunkMd5 = await this.getMd5(chunk);
        if (arr.length > 0 && arr.includes(index)) {
          this.uploadChunk(chunk, md5, index, chunkMd5, type);
        } else if (arr.length == 0) {
          this.uploadChunk(chunk, md5, index, chunkMd5, type);
        }
        start = end;
        end = start + chunkSize;
        index++;
      }
    },
    // 2.每一片携带主文件md5 和自身的md5 异步上传100片
    uploadChunk(chunk, md5, index, chunkMd5, type) {
      let formData = new FormData();
      formData.append("md5", md5);
      formData.append("chunkMd5", chunkMd5);
      formData.append("index", index);
      formData.append("type", type);
      formData.append("file", chunk);
      // 判断是否有webworker
      if (window.Worker) {
        const data = {};
        for (const [key, value] of formData.entries()) {
          data[key] = value;
        }
        this.uploadData.webworker(data).then((res) => {
          if (res == "add") {
            this.uploadData.md5Len++;
          }
          if (res == "del") {
            this.uploadData.md5Len--;
          }
        });
      } else {
        fetchUpload("/sdk/uploadchunk", formData)
          .then((res) => {
            this.uploadData.md5Len++;
          })
          .catch((err) => {
            this.uploadData.md5Len--;
          });
      }
    },
  },
};
